package pl.wroc.pwr.mss.server.ui.tables.models;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;

import org.apache.log4j.Logger;

import pl.wroc.pwr.mss.logic.domain.Playlist;
import pl.wroc.pwr.mss.server.service.PlaylistService;

/**
 * Model danych dla tabeli z playlistami.
 * 
 * @author mjagus
 */
public class PlaylistTableModel extends AbstractTableModel implements TableModelListener
{
    /**
     * Identyfikator klasy.
     */
    private static final long serialVersionUID = -9086982678539877599L;

    /**
     * Logger tej klasy.
     */
    private static final Logger log = Logger.getLogger(PlaylistTableModel.class);

    /**
     * Tablica nazw kolumn.
     */
    private static final String[] columnNames = {"Playlist"};

    /**
     * Predefiniowany komparator Playlist porownujacy ich nazwy.
     */
    private static final Comparator<Playlist> PLAYLIST_NAME_COMPARATOR = new Comparator<Playlist>() {

        @Override
        public int compare(Playlist a, Playlist b) {
            return a.getName().compareTo(b.getName());
        }

    };

    /**
     * Serwis dla encji playlist.
     */
    private PlaylistService playlistService;

    /**
     * Skeszowana lista playlist. Wprowadzona aby ograniczyc liczbe zapytan
     * wysylanych do bazy.
     */
    private List<Playlist> playlists;

    /**
     * Iniciuje model.
     */
    public PlaylistTableModel()
    {
        super();
        super.addTableModelListener(this);

        this.playlists = new ArrayList<Playlist>();
    }

    /**
     * Aktualizuje skeszowana liste playlist.
     */
    private void updatePlaylists()
    {
        playlists.clear();
        playlists.addAll(playlistService.findAll());
        Collections.sort(playlists, PLAYLIST_NAME_COMPARATOR);

        log.info("Playlist cache updated.");
    }

    @Override
    public Class<?> getColumnClass(int columnIndex)
    {
        return String.class;
    }

    @Override
    public int getColumnCount()
    {
        return 1;
    }

    @Override
    public String getColumnName(int columnIndex)
    {
        return columnNames[columnIndex];
    }

    @Override
    public int getRowCount()
    {
        return playlists.size();
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex)
    {
        return playlists.get(rowIndex).getName();
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex)
    {
        return false;
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex)
    {
        throw new UnsupportedOperationException("Cell is not editable");
    }

    @Override
    public void tableChanged(TableModelEvent e)
    {
        updatePlaylists();
    }

    /**
     * @return Serwis dla encji Playlist
     */
    public PlaylistService getPlaylistService()
    {
        return playlistService;
    }

    /**
     * @param playlistService Serwis dla encji Playlist do ustawienia
     */
    public void setPlaylistService(PlaylistService playlistService)
    {
        this.playlistService = playlistService;
    }

    /**
     * @return Skeszowana lista playlist przechowywana przez ten model
     */
    public List<Playlist> getPlaylists()
    {
        return playlists;
    }

    /**
     * @param playlists Skeszowana lista playlist przechowywana przez ten model
     */
    public void setPlaylists(List<Playlist> playlists)
    {
        this.playlists = playlists;
        super.fireTableDataChanged();
    }
}
